package com.lb.poitl;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.apache.poi.xwpf.usermodel.XWPFRun;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.nodes.Node;
import org.jsoup.nodes.TextNode;

import com.deepoove.poi.XWPFTemplate;
import com.deepoove.poi.data.style.Style;
import com.deepoove.poi.policy.AbstractRenderPolicy;
import com.deepoove.poi.render.RenderContext;
import com.deepoove.poi.xwpf.NiceXWPFDocument;
import com.lb.poitl.handler.BaseHtmlTagHandler;
import com.lb.poitl.handler.BrTagHandler;
import com.lb.poitl.handler.CommonTextTagHandler;
import com.lb.poitl.handler.ItalicTagHandler;
import com.lb.poitl.handler.SpanTagHandler;
import com.lb.poitl.handler.StrongTagHandler;

import cn.hutool.core.bean.BeanUtil;

/**
 * @author jzhang
 * @version 1.0
 * @date 2022/5/30 15:46
 */
public class HtmlRenderPolicy extends AbstractRenderPolicy<String> {

    private static final Map<String, BaseHtmlTagHandler> HANDLER_MAP = new HashMap<>();

    static {
        HANDLER_MAP.put("", new CommonTextTagHandler());
        HANDLER_MAP.put("strong", new StrongTagHandler());
        HANDLER_MAP.put("i", new ItalicTagHandler());
        HANDLER_MAP.put("span", new SpanTagHandler());
        HANDLER_MAP.put("br", new BrTagHandler());
    }

    @Override
    public void doRender(RenderContext<String> context) {
        Object data = context.getData();
        XWPFTemplate template = context.getTemplate();
        XWPFRun run = context.getRun();

        if (data == null || StringUtils.isBlank(data.toString())) {
            return;
        }

        //获得Apache POI增强类NiceXWPFDocument
        NiceXWPFDocument doc = template.getXWPFDocument();

        String html = data.toString();
        html = html.replaceAll("&gt;", ">")
                .replaceAll("&lt;", "<")
                .replaceAll("&nbsp;", " ")
                .replaceAll("\\n", "")
                .replaceAll("<p>", "")
                .replaceAll("</p>", "");

        Document document = Jsoup.parse(html);
        List<Node> nodeList = document.body().childNodes();

        HandlerParams handlerParams = new HandlerParams();
        handlerParams.setCurrentRun(run);

        for (Node e : nodeList) {
            handlerParams.setCurrentNode(e);
            parseHtmlToWord(handlerParams, new Style());
        }
    }

    @Override
    protected void afterRender(RenderContext<String> context) {
        clearPlaceholder(context, true);
    }

    public void parseHtmlToWord(HandlerParams handlerParams, Style style) {
        Node ele = handlerParams.getCurrentNode();
        BaseHtmlTagHandler handler = getHandler("");
        if (ele instanceof Element) {
            handler = getHandler(((Element) ele).tagName());
            handler.handleHtmlElement(handlerParams, style);
        } else if (ele instanceof TextNode) {
            handler.handleHtmlElement(handlerParams, style);
        }

        if (ele.childNodes().size() > 0) {
            for (Node node : ele.childNodes()) {
                handlerParams.setCurrentNode(node);
                parseHtmlToWord(handlerParams, copyStyle(style));
            }
        }
    }

    private static Style copyStyle(Style style){
        if (style == null) {
            return new Style();
        }

        Style style1 = new Style();
        BeanUtil.copyProperties(style, style1);
        return style1;
    }

    private static BaseHtmlTagHandler getHandler(String tagName){
        if (tagName == null) {
            return null;
        }
        for (String key:HANDLER_MAP.keySet()) {
            if (key.equalsIgnoreCase(tagName) || tagName.toUpperCase().matches(key.toUpperCase())) {
                return HANDLER_MAP.get(key);
            }
        }

        return HANDLER_MAP.get("");
    }
}
